package httpproxy.service;

import java.io.BufferedInputStream;
import java.io.InputStream;
import java.net.UnknownHostException;
import java.util.Enumeration;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.httpclient.Header;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

@Service
public class ProxyService {
	private static final String[] filterAddress = { "127.0.0.0", "127.0.0.1", "localhost" };

	public void proxyGetRequest(HttpServletRequest servletRequest, HttpServletResponse servletResponse) {
		try {
			if (this.filterLocalRequest(servletRequest.getRequestURL().toString())) {
				return;
			}
			HttpClient client = new HttpClient();
			GetMethod getMethod = new GetMethod(servletRequest.getRequestURL().toString());
			Enumeration<String> enums = servletRequest.getHeaderNames();
			while (enums.hasMoreElements()) {
				String headerName = enums.nextElement();
				if (headerName.contains("proxy")) {
					continue;
				}
				if (headerName.contains("accept-encoding")) {
					continue;
				}
				String headerValue = servletRequest.getHeader(headerName);
				getMethod.addRequestHeader(headerName, headerValue);
				System.out.println(headerName + "   ----  " + headerValue);
			}
			client.executeMethod(getMethod);

			boolean isText = false;
			boolean isChunked = false;
			servletResponse.setHeader("Access-Control-Allow-Origin", "*");
			for (Header header : getMethod.getResponseHeaders()) {
				if (header.getName().equals("Content-Type") && header.getValue().contains("text")) {
					isText = true;
				}
				if (header.getName().equals("Transfer-Encoding") && header.getValue().equals("chunked")) {
					isChunked = true;
				}
				servletResponse.setHeader(header.getName(), header.getValue());
				System.out.println(header.getName() + "   ----  " + header.getValue());
			}
			if (isText) {
				String s = getMethod.getResponseBodyAsString();
				System.out.println(s);
				servletResponse.getWriter().write(s);
			} else {
				InputStream responseBodyAsStream = getMethod.getResponseBodyAsStream();
				BufferedInputStream instream = new BufferedInputStream(responseBodyAsStream);
				int j = 0;
				while ((j = instream.read()) != -1) {
					servletResponse.getWriter().write(j);
				}
			}
		} catch (UnknownHostException e) {
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public void proxyPostRequest(HttpServletRequest servletRequest, HttpServletResponse servletResponse) {
		try {
			if (this.filterLocalRequest(servletRequest.getRequestURL().toString())) {
				return;
			}
			HttpClient client = new HttpClient();
			PostMethod postMethod = new PostMethod(servletRequest.getRequestURL().toString());
			Enumeration<String> enums = servletRequest.getHeaderNames();
			while (enums.hasMoreElements()) {
				String headerName = enums.nextElement();
				if (headerName.contains("proxy")) {
					continue;
				}
				String headerValue = servletRequest.getHeader(headerName);
				postMethod.addRequestHeader(headerName, headerValue);
				System.out.println(headerName + "   ----  " + headerValue);
			}
			client.executeMethod(postMethod);

			boolean isText = false;
			servletResponse.setHeader("Access-Control-Allow-Origin", "*");
			for (Header header : postMethod.getResponseHeaders()) {
				if (header.getName().equals("Content-Type") && header.getValue().contains("text")) {
					isText = true;
				}
				servletResponse.setHeader(header.getName(), header.getValue());
			}
			if (isText) {
				String s = postMethod.getResponseBodyAsString();
				System.out.println(s);
				servletResponse.getWriter().write(s);
			} else {
				InputStream responseBodyAsStream = postMethod.getResponseBodyAsStream();
				BufferedInputStream instream = new BufferedInputStream(responseBodyAsStream);
				int j = 0;
				while ((j = instream.read()) != -1) {
					servletResponse.getWriter().write(j);
				}
			}
		} catch (UnknownHostException e) {
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	private boolean filterLocalRequest(String address) {
		if (StringUtils.isEmpty(address)) {
			return true;
		}
		for (String one : filterAddress) {
			if (address.contains(one)) {
				return true;
			}
		}
		return false;
	}
}
